﻿using ChholCmdPort;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace ChholConfig.UserSerial {
	internal class UserSerialPort : IDisposable {

		public readonly Action<Pkg> dSendData;
		public readonly Dictionary<ushort, NodesSerialportForm>  node_form_DIC = new Dictionary<ushort, NodesSerialportForm>();
		public Form main_form;
		private bool disposedValue;
		const byte remote_port = 112;

		public UserSerialPort(Action<Pkg> dSendData) {
			this.dSendData = dSendData ?? throw new ArgumentNullException(nameof(dSendData));
		}

		public bool recvPkg(Pkg pkg) {
			if ((pkg.From_port != remote_port)||(disposedValue==true)) {
				return false;
			}
			main_form.BeginInvoke(new Action<Pkg>(receivePkg), pkg);
			return true;
		}
		public event EventHandler<CreateRemoteFormEventArgs> eCreateRemoteForm;


		public NodesSerialportForm createRemoteDuplex(ushort addr) {
			NodesSerialportForm form;
			lock (node_form_DIC) {
				if (node_form_DIC.ContainsKey(addr)) {
					return null;
				}
				form = new NodesSerialportForm(new DuplexCc9d(addr, remote_port, dSendData));
				node_form_DIC.Add(addr, form);
			}
			eCreateRemoteForm?.Invoke(this, new CreateRemoteFormEventArgs(form, addr));
			form.Show();
			form.FormClosing += Form_FormClosing;
			return form;
		}
		public void receivePkg(Pkg pkg) {
			DuplexCc9d duplex = null;
			lock (node_form_DIC) {
				if (node_form_DIC.ContainsKey(pkg.Remote_addr)) {
					duplex = node_form_DIC[pkg.Remote_addr].mainStm.Port as DuplexCc9d;
				}
			}
			if (duplex == null) {
				duplex = createRemoteDuplex(pkg.Remote_addr).mainStm.Port as DuplexCc9d;
			}
			duplex.recvCc9dPkg(pkg);
		}
		bool is_disposing_closingForm = false;

		private void Form_FormClosing(object sender, FormClosingEventArgs e) {
			if (is_disposing_closingForm == false) {
				MessageBox.Show("不要关闭自动打开的用户串口调试窗口，如需要全部关闭，请关闭主窗口。");
				e.Cancel = true;
			}
		}

		protected virtual void Dispose(bool disposing) {
			if (!disposedValue) {
				if (disposing) {
					is_disposing_closingForm = true;
					foreach (var form in node_form_DIC.Values) {
						form.Close(); form.Dispose();
					}
					node_form_DIC.Clear();
				}

				// TODO: 释放未托管的资源(未托管的对象)并重写终结器
				// TODO: 将大型字段设置为 null
				disposedValue = true;
			}
		}

		// // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
		// ~UserSerialPort()
		// {
		//     // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
		//     Dispose(disposing: false);
		// }

		public void Dispose() {
			// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}
		public Action dShowForm;
		public Action dClose;

		public event EventHandler ePortNameChanged;
		public event EventHandler eClosed;

		public void showForm() {
			dShowForm();
		}
		public void forceClose() {
			foreach (var f in node_form_DIC.Values) {
				f.Close();
				f.Dispose();
				
			}
		}



	}
}
